﻿using Styx;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using System.Text.RegularExpressions;
using System.Linq;
using System.Globalization;
using Styx.Common;
using System;
using System.IO;
using Styx.CommonBot.Frames;
using System.Diagnostics;

namespace GatherHelper
{
    class Helpers
    {

        #region GlobalVars

        public static LocalPlayer Me { get { return StyxWoW.Me; } }

        #endregion

        #region MountHelpers

        public static ShapeshiftForm shapeshift = StyxWoW.Me.Shapeshift;

        public static bool checkZ(WoWGameObject myNode) { return ((myNode.Z - Me.Z) < 0); }

        public static bool IsDruid() { return (Me.Class == WoWClass.Druid); }

        public static bool IsDistanceGood(WoWGameObject myNode) { return (myNode.Distance <= GatherHelperSettings.Instance.DistanceToDismount); }

        public static bool IsBotGBorPB(string myBot) { return (myBot.Contains("Gather") || myBot.Contains("Profession")); }

        public static bool ShapeShiftCheck(ShapeshiftForm myShift) { return (shapeshift == ShapeshiftForm.FlightForm || shapeshift == ShapeshiftForm.EpicFlightForm); }

        #endregion

        #region StuckHelpers

        public static WoWPoint ToHotspot()
        {
            const string negativeHotspotRegex = "-[0-9]*.[0-9]*, [0-9]*.[0-9]*.[0-9]*.[0-9]*, [0-9]*.[0-9]*";
            const string positiveHotspotRegex = "[0-9]*.[0-9]*, [0-9]*.[0-9]*.[0-9]*.[0-9]*, [0-9]*.[0-9]*";
            var negativeHotspot = Regex.Match(GetValueFromFile(), negativeHotspotRegex, RegexOptions.IgnoreCase);
            var positiveHotspot = Regex.Match(GetValueFromFile(), positiveHotspotRegex, RegexOptions.IgnoreCase);
            var negativeList = negativeHotspot.Value.Split(',').Where(str => str != null).ToList();
            var postiveList = positiveHotspot.Value.Split(',').Where(str => str != null).ToList();

            try
            {
                if (StyxWoW.Me.Location.X.ToString(CultureInfo.InvariantCulture).Contains("-"))
                {
                    var hotspotFull = new WoWPoint(float.Parse(negativeList[0]),
                        float.Parse(negativeList[1]),
                        float.Parse(negativeList[2]));
                    return hotspotFull;
                }
                else
                {
                    var hotspotFull = new WoWPoint(float.Parse(postiveList[0]),
                        float.Parse(postiveList[1]),
                        float.Parse(postiveList[2]));
                    return hotspotFull;
                }

            }
            catch (Exception e)
            {
                Logging.Write("Error: " + e.Message + e.Data + e.Source);
            }

            return new WoWPoint();
        }

        public static bool IsStuck()
        {
            return ToHotspot().Distance(StyxWoW.Me.Location) < 30 &&
                   !StyxWoW.Me.Combat &&
                   !StyxWoW.Me.IsCasting &&
                   !StyxWoW.Me.IsChanneling &&
                   !StyxWoW.Me.IsSwimming &&
                   !Me.HasAura(15007) &&
                   StyxWoW.Me.ZoneId != 493 &&
                   !QuestFrame.Instance.IsVisible &&
                   !IsTravelling() &&
                   !StyxWoW.Me.HasAura("Food") &&
                   !StyxWoW.Me.HasAura("Drink") &&
                   /*BotPoi.Current.Type != PoiType.Repair &&
                   BotPoi.Current.Type != PoiType.Mail &&*/
                   !ObjectManager.GetObjectsOfTypeFast<WoWUnit>().Any(
                       u => u.Distance < 15 &&
                            u.IsRepairMerchant
                        ) &&
                   !NeedRegen;
        }

        public static bool IsStuckInCombatWithoutEnemies()
        {
            return ToHotspot().Distance(StyxWoW.Me.Location) < 30 &&
                   StyxWoW.Me.Combat &&
                   !ObjectManager.GetObjectsOfTypeFast<WoWUnit>().Any(
                       u => u.Combat && 
                            u.CurrentTarget == Me && 
                            u.Distance < 30) &&
                   !StyxWoW.Me.IsCasting &&
                   !StyxWoW.Me.IsChanneling &&
                   !StyxWoW.Me.IsSwimming &&
                   !Me.HasAura(15007) &&
                   StyxWoW.Me.ZoneId != 493 &&
                   !QuestFrame.Instance.IsVisible &&
                   !IsTravelling();
        }

        public static bool NeedRegen { get { return Me.HealthPercent <= 65; } }

        public static bool IsTravelling() { return ObjectManager.GetObjectsOfType<WoWGameObject>(false, false).Any(ship => ship != null && ship.IsValid && ship.Transport && ship.Distance < 50); }

        public static void ResetTimer(Stopwatch myTimer) { myTimer.Reset(); /*StyxWoW.SleepForLagDuration();*/ }

        public static void StartTimer(Stopwatch myTimer) { myTimer.Start(); } //return SWaitTimer.IsRunning ? SWaitTimer.Elapsed.Seconds : 0;

        #endregion

        #region HotSpotDirFile

        public static string StuckSpotsFileLocation = @"Plugins\GatherHelper\" + StyxWoW.Me.RealmName + @"\" + StyxWoW.Me.Name + ".txt";

        public static void CreateFile()
        {
            if (!Directory.Exists(@"Plugins\GatherHelper\" + StyxWoW.Me.RealmName))
            {
                Directory.CreateDirectory(@"Plugins\GatherHelper\" + StyxWoW.Me.RealmName);
                if (!File.Exists(StuckSpotsFileLocation))
                    File.Create(StuckSpotsFileLocation);
                WriteHotspotToFile();
            }
            else if (!File.Exists(StuckSpotsFileLocation))
                File.Create(StuckSpotsFileLocation);
            WriteHotspotToFile();
        }

        public static void WriteHotspotToFile()
        {
            using (var streamWriter = new StreamWriter(StuckSpotsFileLocation))
            {
                if (GatherHelperSettings.Instance.FileDebug) GatherHelperPlugin.pLog(string.Format("Writing new Hotspot to File : {0}", StyxWoW.Me.Location));
                streamWriter.WriteLineAsync(StyxWoW.Me.Location.ToString());
            }
        }

        public static string GetValueFromFile()
        {
            using (var streamReader = new StreamReader(StuckSpotsFileLocation))
            {
                return streamReader.ReadLine();
            }
        }

        #endregion

    }
}
